#
# Aspia Project
# Copyright (C) 2020 Dmitry Chapyshev <dmitry@aspia.ru>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#

list(APPEND SOURCE_BASE
    base64.cc
    base64.h
    bitset.h
    command_line.cc
    command_line.h
    compiler_specific.h
    converter.h
    cpuid_util.cc
    cpuid_util.h
    crc32.cc
    crc32.h
    debug.cc
    debug.h
    endian_util.cc
    endian_util.h
    environment.cc
    environment.h
    guid.cc
    guid.h
    location.cc
    location.h
    logging.cc
    logging.h
    macros_magic.h
    power_controller.h
    process_handle.cc
    process_handle.h
    scoped_clear_last_error.cc
    scoped_clear_last_error.h
    session_id.cc
    session_id.h
    smbios.h
    smbios_parser.cc
    smbios_parser.h
    smbios_reader.h
    stl_util.h
    sys_info.cc
    sys_info.h
    system_error.cc
    system_error.h
    system_time.cc
    system_time.h
    task_runner.cc
    task_runner.h
    version.cc
    version.h
    waitable_event.cc
    waitable_event.h
    waitable_timer.cc
    waitable_timer.h
    xml_sax_writer.cc
    xml_sax_writer.h)

if (WIN32)
    list(APPEND SOURCE_BASE
        power_controller_win.cc
        smbios_reader_win.cc
        sys_info_win.cc)
endif()

if (LINUX)
    list(APPEND SOURCE_BASE
        power_controller_linux.cc
        smbios_reader_linux.cc
        sys_info_linux.cc)
endif()

if (APPLE)
    list(APPEND SOURCE_BASE
        power_controller_mac.mm
        smbios_reader_mac.mm
        sys_info_mac.mm)
endif()

list(APPEND SOURCE_BASE_TESTS
    base64_unittest.cc
    bitset_unittest.cc
    converter_unittest.cc
    crc32_unittest.cc
    guid_unittest.cc
    scoped_clear_last_error_unittest.cc
    stl_util_unittest.cc
    tests_main.cc
    version_unittest.cc)

list(APPEND SOURCE_BASE_AUDIO
    audio/audio_capturer.cc
    audio/audio_capturer.h
    audio/audio_capturer_wrapper.cc
    audio/audio_capturer_wrapper.h
    audio/audio_output.cc
    audio/audio_output.h
    audio/audio_player.cc
    audio/audio_player.h
    audio/audio_silence_detector.cc
    audio/audio_silence_detector.h
    audio/audio_volume_filter.cc
    audio/audio_volume_filter.h)

if (WIN32)
    list(APPEND SOURCE_BASE_AUDIO
        audio/audio_capturer_win.cc
        audio/audio_capturer_win.h
        audio/audio_output_win.cc
        audio/audio_output_win.h
        audio/audio_volume_filter_win.cc
        audio/audio_volume_filter_win.h)

    list(APPEND SOURCE_BASE_AUDIO_WIN
        audio/win/audio_util_win.cc
        audio/win/audio_util_win.h
        audio/win/default_audio_device_change_detector.cc
        audio/win/default_audio_device_change_detector.h
        audio/win/scoped_mmcss_registration.cc
        audio/win/scoped_mmcss_registration.h)
endif()

if (LINUX)
    list(APPEND SOURCE_BASE_AUDIO
        audio/audio_output_pulse.cc
        audio/audio_output_pulse.h)

    list(APPEND SOURCE_BASE_AUDIO_LINUX
        audio/linux/late_binding_symbol_table.cc
        audio/linux/late_binding_symbol_table.h
        audio/linux/pulseaudio_symbol_table.cc
        audio/linux/pulseaudio_symbol_table.h)
endif()

if (APPLE)
    list(APPEND SOURCE_BASE_AUDIO
        audio/audio_output_mac.cc
        audio/audio_output_mac.h)
endif()

list(APPEND SOURCE_BASE_CODEC
    codec/audio_bus.cc
    codec/audio_bus.h
    codec/audio_decoder.cc
    codec/audio_decoder.h
    codec/audio_decoder_opus.cc
    codec/audio_decoder_opus.h
    codec/audio_encoder.h
    codec/audio_encoder_opus.cc
    codec/audio_encoder_opus.h
    codec/audio_sample_types.h
    codec/cursor_decoder.cc
    codec/cursor_decoder.h
    codec/cursor_encoder.cc
    codec/cursor_encoder.h
    codec/multi_channel_resampler.cc
    codec/multi_channel_resampler.h
    codec/scale_reducer.cc
    codec/scale_reducer.h
    codec/scoped_vpx_codec.cc
    codec/scoped_vpx_codec.h
    codec/scoped_zstd_stream.cc
    codec/scoped_zstd_stream.h
    codec/sinc_resampler.cc
    codec/sinc_resampler.h
    codec/vector_math.cc
    codec/vector_math.h
    codec/video_decoder.cc
    codec/video_decoder.h
    codec/video_decoder_vpx.cc
    codec/video_decoder_vpx.h
    codec/video_encoder.cc
    codec/video_encoder.h
    codec/video_encoder_vpx.cc
    codec/video_encoder_vpx.h)

list(APPEND SOURCE_BASE_CRYPTO
    crypto/big_num.cc
    crypto/big_num.h
    crypto/data_cryptor.h
    crypto/data_cryptor_chacha20_poly1305.cc
    crypto/data_cryptor_chacha20_poly1305.h
    crypto/data_cryptor_fake.cc
    crypto/data_cryptor_fake.h
    crypto/generic_hash.cc
    crypto/generic_hash.h
    crypto/key_pair.cc
    crypto/key_pair.h
    crypto/large_number_increment.cc
    crypto/large_number_increment.h
    crypto/message_decryptor.h
    crypto/message_decryptor_fake.cc
    crypto/message_decryptor_fake.h
    crypto/message_decryptor_openssl.cc
    crypto/message_decryptor_openssl.h
    crypto/message_encryptor.h
    crypto/message_encryptor_fake.cc
    crypto/message_encryptor_fake.h
    crypto/message_encryptor_openssl.cc
    crypto/message_encryptor_openssl.h
    crypto/openssl_util.cc
    crypto/openssl_util.h
    crypto/os_crypt.h
    crypto/password_generator.cc
    crypto/password_generator.h
    crypto/password_hash.cc
    crypto/password_hash.h
    crypto/random.cc
    crypto/random.h
    crypto/scoped_crypto_initializer.cc
    crypto/scoped_crypto_initializer.h
    crypto/secure_memory.cc
    crypto/secure_memory.h
    crypto/srp_constants.cc
    crypto/srp_constants.h
    crypto/srp_math.cc
    crypto/srp_math.h)

if (WIN32)
    list(APPEND SOURCE_BASE_CRYPTO crypto/os_crypt_win.cc)
endif()

if (APPLE)
    list(APPEND SOURCE_BASE_CRYPTO crypto/os_crypt_mac.mm)
endif()

if (LINUX)
    list(APPEND SOURCE_BASE_CRYPTO crypto/os_crypt_linux.cc)
endif()

list(APPEND SOURCE_BASE_CRYPTO_TESTS
    crypto/big_num_unittest.cc
    crypto/cryptor_unittest.cc
    crypto/data_cryptor_unittest.cc
    crypto/generic_hash_unittest.cc
    crypto/key_pair_unittest.cc
    crypto/large_number_increment_unittest.cc
    crypto/password_generator_unittest.cc
    crypto/password_hash_unittest.cc
    crypto/srp_math_unittest.cc)

list(APPEND SOURCE_BASE_DESKTOP
    desktop/capture_scheduler.cc
    desktop/capture_scheduler.h
    desktop/cursor_capturer.h
    desktop/desktop_environment.cc
    desktop/desktop_environment.h
    desktop/diff_block_32bpp_c.cc
    desktop/diff_block_32bpp_c.h
    desktop/diff_block_32bpp_sse2.cc
    desktop/diff_block_32bpp_sse2.h
    desktop/differ.cc
    desktop/differ.h
    desktop/frame.cc
    desktop/frame.h
    desktop/frame_aligned.cc
    desktop/frame_aligned.h
    desktop/frame_rotation.cc
    desktop/frame_rotation.h
    desktop/frame_simple.cc
    desktop/frame_simple.h
    desktop/geometry.cc
    desktop/geometry.h
    desktop/mouse_cursor.cc
    desktop/mouse_cursor.h
    desktop/power_save_blocker.cc
    desktop/power_save_blocker.h
    desktop/region.cc
    desktop/region.h
    desktop/screen_capturer.cc
    desktop/screen_capturer.h
    desktop/screen_capturer_wrapper.cc
    desktop/screen_capturer_wrapper.h
    desktop/shared_frame.cc
    desktop/shared_frame.h
    desktop/shared_memory_frame.cc
    desktop/shared_memory_frame.h)

if (WIN32)
    list(APPEND SOURCE_BASE_DESKTOP
        desktop/cursor_capturer_win.cc
        desktop/cursor_capturer_win.h
        desktop/desktop_environment_win.cc
        desktop/frame_dib.cc
        desktop/frame_dib.h
        desktop/screen_capturer_dxgi.cc
        desktop/screen_capturer_dxgi.h
        desktop/screen_capturer_gdi.cc
        desktop/screen_capturer_gdi.h)
endif()

if (LINUX)
    list(APPEND SOURCE_BASE_DESKTOP
        desktop/cursor_capturer_x11.cc
        desktop/cursor_capturer_x11.h
        desktop/desktop_environment_linux.cc
        desktop/screen_capturer_x11.cc
        desktop/screen_capturer_x11.h)
endif()

if (APPLE)
    list(APPEND SOURCE_BASE_DESKTOP
        desktop/cursor_capturer_mac.mm
        desktop/cursor_capturer_mac.h
        desktop/desktop_environment_mac.mm
        desktop/screen_capturer_mac.mm
        desktop/screen_capturer_mac.h)
endif()

list(APPEND SOURCE_BASE_DESKTOP_TESTS
    desktop/diff_block_32bpp_c_unittest.cc
    desktop/diff_block_32bpp_sse2_unittest.cc
    desktop/frame_unittest.cc
    desktop/geometry_unittest.cc
    desktop/region_unittest.cc)

if (WIN32)
    list(APPEND SOURCE_BASE_DESKTOP_WIN
        desktop/win/bitmap_info.h
        desktop/win/cursor.cc
        desktop/win/cursor.h
        desktop/win/d3d_device.cc
        desktop/win/d3d_device.h
        desktop/win/display_configuration_monitor.cc
        desktop/win/display_configuration_monitor.h
        desktop/win/dxgi_adapter_duplicator.cc
        desktop/win/dxgi_adapter_duplicator.h
        desktop/win/dxgi_context.cc
        desktop/win/dxgi_context.h
        desktop/win/dxgi_duplicator_controller.cc
        desktop/win/dxgi_duplicator_controller.h
        desktop/win/dxgi_frame.cc
        desktop/win/dxgi_frame.h
        desktop/win/dxgi_output_duplicator.cc
        desktop/win/dxgi_output_duplicator.h
        desktop/win/dxgi_texture.cc
        desktop/win/dxgi_texture.h
        desktop/win/dxgi_texture_mapping.cc
        desktop/win/dxgi_texture_mapping.h
        desktop/win/dxgi_texture_staging.cc
        desktop/win/dxgi_texture_staging.h
        desktop/win/screen_capture_utils.cc
        desktop/win/screen_capture_utils.h)

    list(APPEND SOURCE_BASE_DESKTOP_WIN_TESTS
        desktop/win/cursor_unittest.cc
        desktop/win/cursor_unittest_resources.h
        desktop/win/cursor_unittest_resources.rc)
endif()

list(APPEND SOURCE_BASE_FILES
    files/base_paths.cc
    files/base_paths.h
    files/file_path_watcher.cc
    files/file_path_watcher.h
    files/file_util.cc
    files/file_util.h
    files/scoped_temp_file.cc
    files/scoped_temp_file.h)

if (WIN32)
    list(APPEND SOURCE_BASE_FILES
        files/file_path_watcher_win.cc)
endif()

if (LINUX)
    list(APPEND SOURCE_BASE_FILES
        files/file_path_watcher_linux.cc)
endif()

if (APPLE)
    list(APPEND SOURCE_BASE_FILES
        files/base_paths_mac.mm
        files/file_path_watcher_mac.cc)
endif()

if (UNIX)
    list(APPEND SOURCE_BASE_FILES
        files/file_descriptor_watcher_posix.cc
        files/file_descriptor_watcher_posix.h)
endif()

list(APPEND SOURCE_BASE_IPC
    ipc/ipc_channel.cc
    ipc/ipc_channel.h
    ipc/ipc_channel_proxy.cc
    ipc/ipc_channel_proxy.h
    ipc/ipc_server.cc
    ipc/ipc_server.h
    ipc/shared_memory.cc
    ipc/shared_memory.h
    ipc/shared_memory_factory.cc
    ipc/shared_memory_factory.h
    ipc/shared_memory_factory_proxy.cc
    ipc/shared_memory_factory_proxy.h)

if (APPLE)
    list(APPEND SOURCE_BASE_MAC
        mac/app_nap_blocker.mm
        mac/app_nap_blocker.h
        mac/nsstring_conversions.mm
        mac/nsstring_conversions.h)
endif()

list(APPEND SOURCE_BASE_MEMORY
    memory/aligned_memory.cc
    memory/aligned_memory.h
    memory/byte_array.cc
    memory/byte_array.h
    memory/typed_buffer.h)

list(APPEND SOURCE_BASE_MEMORY_TESTS
    memory/aligned_memory_unittest.cc
    memory/byte_array_unittest.cc)

list(APPEND SOURCE_BASE_MESSAGE_LOOP
    message_loop/message_loop.cc
    message_loop/message_loop.h
    message_loop/message_loop_task_runner.cc
    message_loop/message_loop_task_runner.h
    message_loop/message_pump.h
    message_loop/message_pump_asio.cc
    message_loop/message_pump_asio.h
    message_loop/message_pump_default.cc
    message_loop/message_pump_default.h
    message_loop/message_pump_dispatcher.h
    message_loop/pending_task.cc
    message_loop/pending_task.h)

if (WIN32)
    list(APPEND SOURCE_BASE_MESSAGE_LOOP
        message_loop/message_pump_win.cc
        message_loop/message_pump_win.h)
endif()

list(APPEND SOURCE_BASE_NET
    net/adapter_enumerator.cc
    net/adapter_enumerator.h
    net/address.cc
    net/address.h
    net/ip_util.cc
    net/ip_util.h
    net/network_channel.cc
    net/network_channel.h
    net/network_channel_proxy.cc
    net/network_channel_proxy.h
    net/network_server.cc
    net/network_server.h
    net/tcp_keep_alive.cc
    net/tcp_keep_alive.h
    net/variable_size.cc
    net/variable_size.h
    net/write_task.h)

if (WIN32)
    list(APPEND SOURCE_BASE_NET
        net/firewall_manager.cc
        net/firewall_manager.h)
endif()

list(APPEND SOURCE_BASE_NET_TESTS
    net/address_unittest.cc)

list(APPEND SOURCE_BASE_PEER
    peer/authenticator.cc
    peer/authenticator.h
    peer/client_authenticator.cc
    peer/client_authenticator.h
    peer/host_id.cc
    peer/host_id.h
    peer/relay_peer.cc
    peer/relay_peer.h
    peer/relay_peer_manager.cc
    peer/relay_peer_manager.h
    peer/server_authenticator.cc
    peer/server_authenticator.h
    peer/server_authenticator_manager.cc
    peer/server_authenticator_manager.h
    peer/user.cc
    peer/user.h
    peer/user_list.cc
    peer/user_list.h
    peer/user_list_base.h)

list(APPEND SOURCE_BASE_SETTINGS
    settings/json_settings.cc
    settings/json_settings.h
    settings/settings.cc
    settings/settings.h
    settings/xml_settings.cc
    settings/xml_settings.h)

list(APPEND SOURCE_BASE_SETTINGS_TESTS
    settings/json_settings_unittest.cc
    settings/xml_settings_unittest.cc)

list(APPEND SOURCE_BASE_STRINGS
    strings/strcat.cc
    strings/strcat.h
    strings/string_number_conversions.cc
    strings/string_number_conversions.h
    strings/string_printf.cc
    strings/string_printf.h
    strings/string_split.cc
    strings/string_split.h
    strings/string_util.cc
    strings/string_util.h
    strings/string_util_constants.cc
    strings/string_util_constants.h
    strings/unicode.cc
    strings/unicode.h)

if (WIN32)
    list(APPEND SOURCE_BASE_STRINGS
        strings/string_util_win.cc)
endif()

if (UNIX)
    list(APPEND SOURCE_BASE_STRINGS
        strings/string_util_icu.cc)
endif()

list(APPEND SOURCE_BASE_STRINGS_TESTS
    strings/string_number_conversions_unittest.cc
    strings/string_printf_unittest.cc
    strings/string_split_unittest.cc
    strings/string_util_unittest.cc)

list(APPEND SOURCE_BASE_THREADING
    threading/simple_thread.cc
    threading/simple_thread.h
    threading/thread.cc
    threading/thread.h
    threading/thread_checker.cc
    threading/thread_checker.h)

if (WIN32)
    list(APPEND SOURCE_BASE_WIN
        win/desktop.cc
        win/desktop.h
        win/drive_enumerator.cc
        win/drive_enumerator.h
        win/file_version_info.cc
        win/file_version_info.h
        win/message_window.cc
        win/message_window.h
        win/object_watcher.cc
        win/object_watcher.h
        win/printer_enumerator.cc
        win/printer_enumerator.h
        win/process.cc
        win/process.h
        win/process_util.cc
        win/process_util.h
        win/registry.cc
        win/registry.h
        win/resource_util.cc
        win/resource_util.h
        win/scoped_clipboard.cc
        win/scoped_clipboard.h
        win/scoped_co_mem.h
        win/scoped_com_initializer.cc
        win/scoped_com_initializer.h
        win/scoped_gdi_object.h
        win/scoped_hdc.h
        win/scoped_hglobal.h
        win/scoped_impersonator.cc
        win/scoped_impersonator.h
        win/scoped_local.h
        win/scoped_object.h
        win/scoped_select_object.h
        win/scoped_thread_desktop.cc
        win/scoped_thread_desktop.h
        win/scoped_user_object.h
        win/scoped_wts_memory.h
        win/security_helpers.cc
        win/security_helpers.h
        win/service.cc
        win/service.h
        win/service_controller.cc
        win/service_controller.h
        win/session_enumerator.cc
        win/session_enumerator.h
        win/session_info.cc
        win/session_info.h
        win/session_status.cc
        win/session_status.h
        win/session_watcher.cc
        win/session_watcher.h
        win/windows_version.cc
        win/windows_version.h)

    list(APPEND SOURCE_BASE_WIN_TESTS
        win/registry_unittest.cc
        win/scoped_object_unittest.cc)
endif()

if (LINUX)
    list(APPEND SOURCE_BASE_X11
        x11/x_server_clipboard.cc
        x11/x_server_clipboard.h)
endif()

source_group("" FILES ${SOURCE_BASE} ${SOURCE_BASE_TESTS})
source_group(audio FILES ${SOURCE_BASE_AUDIO})
source_group(codec FILES ${SOURCE_BASE_CODEC})
source_group(crypto FILES ${SOURCE_BASE_CRYPTO} ${SOURCE_BASE_CRYPTO_TESTS})
source_group(desktop FILES ${SOURCE_BASE_DESKTOP} ${SOURCE_BASE_DESKTOP_TESTS})
source_group(files FILES ${SOURCE_BASE_FILES})
source_group(ipc FILES ${SOURCE_BASE_IPC})
source_group(memory FILES ${SOURCE_BASE_MEMORY} ${SOURCE_BASE_MEMORY_TESTS})
source_group(message_loop FILES ${SOURCE_BASE_MESSAGE_LOOP})
source_group(net FILES ${SOURCE_BASE_NET} ${SOURCE_BASE_NET_TESTS})
source_group(peer FILES ${SOURCE_BASE_PEER})
source_group(settings FILES ${SOURCE_BASE_SETTINGS} ${SOURCE_BASE_SETTINGS_TESTS})
source_group(strings FILES ${SOURCE_BASE_STRINGS} ${SOURCE_BASE_STRINGS_TESTS})
source_group(threading FILES ${SOURCE_BASE_THREADING})

if (WIN32)
    source_group(audio\\win FILES ${SOURCE_BASE_AUDIO_WIN})
    source_group(desktop\\win FILES ${SOURCE_BASE_DESKTOP_WIN} ${SOURCE_BASE_DESKTOP_WIN_TESTS})
    source_group(win FILES ${SOURCE_BASE_WIN} ${SOURCE_BASE_WIN_TESTS})
endif()

if (LINUX)
    source_group(audio\\linux FILES ${SOURCE_BASE_AUDIO_LINUX})
    source_group(x11 FILES ${SOURCE_BASE_X11})
endif()

if (APPLE)
    source_group(mac FILES ${SOURCE_BASE_MAC})
endif()

add_library(aspia_base STATIC
    ${SOURCE_BASE}
    ${SOURCE_BASE_AUDIO}
    ${SOURCE_BASE_AUDIO_LINUX}
    ${SOURCE_BASE_AUDIO_WIN}
    ${SOURCE_BASE_CODEC}
    ${SOURCE_BASE_CRYPTO}
    ${SOURCE_BASE_DESKTOP}
    ${SOURCE_BASE_DESKTOP_WIN}
    ${SOURCE_BASE_FILES}
    ${SOURCE_BASE_IPC}
    ${SOURCE_BASE_MAC}
    ${SOURCE_BASE_MEMORY}
    ${SOURCE_BASE_MESSAGE_LOOP}
    ${SOURCE_BASE_NET}
    ${SOURCE_BASE_PEER}
    ${SOURCE_BASE_SETTINGS}
    ${SOURCE_BASE_STRINGS}
    ${SOURCE_BASE_THREADING}
    ${SOURCE_BASE_WIN}
    ${SOURCE_BASE_X11})

if (LINUX)
    set(BASE_PLATFORM_LIBS ${XFIXES_LIB} stdc++fs ICU::uc ICU::dt xdg_user_dirs)
endif()

target_link_libraries(aspia_base aspia_proto ${THIRD_PARTY_LIBS} ${BASE_PLATFORM_LIBS})

if (WIN32)
    set(BASE_TESTS_PLATFORM_LIBS crypt32 iphlpapi ws2_32)
endif()

if (LINUX)
    set(BASE_TESTS_PLATFORM_LIBS stdc++fs ICU::uc ICU::dt)
endif()

if (APPLE)
    set(BASE_TESTS_PLATFORM_LIBS ${FOUNDATION_LIB} ICU::uc ICU::dt)
endif()

add_executable(aspia_base_tests
    ${SOURCE_BASE_TESTS}
    ${SOURCE_BASE_CRYPTO_TESTS}
    ${SOURCE_BASE_DESKTOP_TESTS}
    ${SOURCE_BASE_DESKTOP_WIN_TESTS}
    ${SOURCE_BASE_MEMORY_TESTS}
    ${SOURCE_BASE_NET_TESTS}
    ${SOURCE_BASE_SETTINGS_TESTS}
    ${SOURCE_BASE_STRINGS_TESTS}
    ${SOURCE_BASE_WIN_TESTS})
target_link_libraries(aspia_base_tests
    aspia_base
    aspia_proto
    GTest::gtest
    ${BASE_TESTS_PLATFORM_LIBS}
    ${THIRD_PARTY_LIBS})

add_test(NAME aspia_base_tests COMMAND aspia_base_tests)
